<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<title>svg</title>
		<script src="d3.js"></script>
		<style>
			svg{
				width: 800px;
				height: 500px;
				margin: 0 auto;
				border: 1px solid blue;
				background-color: #f5f6f7;
			}
			.h-bar {
				margin-bottom: 2px;
				border: 1px solid blue;
				background-color: #ccc;
			}
			.v-bar,.cell {
				margin-bottom: 2px;
				margin-right: 2px;
				padding: 10px;
				border: 1px solid blue;
				background-color: #ccc;
			}
			.fixed-cell{
				position:  absolute;
				margin-bottom: 2px;
				margin-right: 2px;
				padding: 10px;
				border: 1px solid blue;
				background-color: #ccc;
			}
		</style>
	</head>
	<body>
		<script> 
			var radius = 30,
				width  = 800,
				height = 600;

			var svg = d3.select("body").append("svg")
				.attr({
					width: width,
					height: height
				});
			
			d3.json("json.json", function(error, graph) { 
				
				graph.links.forEach(function(d) {
					d.source = graph.nodes[d.source];
					d.target = graph.nodes[d.target];
				});

				var links = svg.append("g")
						.attr("class", "links")
					.selectAll("line")
						.data(graph.links);
						
				links.enter()
					.append("line")
					.attr({
						x1: function(d) {
							return d.source.x;
						},
						y1: function(d) {
							return d.source.y;
						},
						x2: function(d) {
							return d.target.x;
						},
						y2: function(d) {
							return d.target.y;
						},
						stroke: "green"
					});

				var start = {cx: 0, cy : 0};
				
				var nodes = svg.append("g")
						.attr("class", "nodes")					
					.selectAll("circle")
						.data(graph.nodes);

				var last_ = -1;
						
				nodes.enter()
					//.append("g")
					//.append("text")
					//.text(function(d) {
					//	return d.labels[0];
					//})
					.append("circle")
					.attr({
						r : radius,
						cx: function(d) {
							return d.x;
						},
						cy: function(d) {
							return d.y;
						},
						fill: function(d) {
							return d.fill;
						}
					})
					.call(d3.behavior.drag()
						.origin(function(d) {
							return d;
						})
						.on("dragstart", function(d) {
							var dragged_ = d3.select(this);
							start.x = dragged_.attr("cx"); 
							start.y = dragged_.attr("cy"); 
						})
						.on("drag", function(d, i) {
							d.x = d3.event.x;
							d.y = d3.event.y;
							var dragged_ = d3.select(this);
							
							dragged_.attr({
								cx: d.x,
								cy: d.y
							});
							links.filter(function(l) {
								return l.source === d;
							})
							.attr({
								x1: d.x,
								y1: d.y
							});

							links.filter(function(l) {
								return l.target === d;
							})
							.attr({
								x2: d.x,
								y2: d.y
							});

							// check the distance
							nodes.filter(function(n) {
								return n !== d;
							})
							.each(function(cur, i) {
								var this_ = d3.select(this);
								
								if (Math.pow(cur.x - d.x, 2)
									+ Math.pow(cur.y - d.y, 2)
									< 2 * Math.pow(radius, 2)) { 
										
									this_.attr("fill", "red");											
									dragged_.attr("fill", "red");
										
									last_ = i; 
								} else {
									if (this_.attr("fill") !== cur.fill) {
										this_.attr("fill", cur.fill);
									}
									if (dragged_.attr("fill") !== d.fill) {
										dragged_.attr("fill", d.fill);
									}
									if (last_ !== -1 && i === last_) {
										last_ = -1;
									}
								}
							});
						})
						.on("dragend", function(d) {
							d.x = start.x;
							d.y = start.y;
							var dragged_ = d3.select(this);
							
							dragged_
								.transition()
								.duration(200)
								.attr({
									cx: d.x,
									cy: d.y,
									fill: d.fill
								});
							
								
							links.filter(function(l) {
								return l.source === d;
							})
							.transition()
							.duration(200)
							.attr({
								x1: d.x,
								y1: d.y
							});
							
							links.filter(function(l) {
								return l.target === d;
							})
							.transition()
							.duration(200)
							.attr({
								x2: d.x,
								y2: d.y
							});
 
							if (last_ !== -1) {
								// need draw a new line
								var temp = graph.nodes[last_];
								d3
									.select(".nodes")
									.selectAll("circle")
									.filter(function(d, i) {
										return i === last_;
									})
									.attr("fill", temp.fill); 

								graph.links.push({"source": temp, "target": d});
								return ;
								svg .select(".links")
									.selectAll("line")
									.data(graph.links)
									.attr({
										x1: function(d) {
											return d.source.x;
										},
										y1: function(d) {
											return d.source.y;
										},
										x2: function(d) {
											return d.target.x;
										},
										y2: function(d) {
											return d.target.y;
										},
										stroke: "green"
									});
							}
						})
					);
					
			})
					
			 
		</script>
	</body>

</html>